package com.lenin.omena.client;

import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.Stack;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.lenin.omena.client.event.DeleteUserEvent;
import com.lenin.omena.client.event.LoginEvent;
import com.lenin.omena.client.event.LoginEvent.ActionType;
import com.lenin.omena.client.event.ProduceListChangeEvent;
import com.lenin.omena.client.event.SaveUserEvent;
import com.lenin.omena.client.event.SaveUserInfoEvent;
import com.lenin.omena.client.event.TestEvent;
import com.lenin.omena.shared.ActivateResult;
import com.lenin.omena.shared.AddProduceResult;
import com.lenin.omena.shared.AppleMarketService;
import com.lenin.omena.shared.AppleMarketServiceAsync;
import com.lenin.omena.shared.DeleteProduceResult;
import com.lenin.omena.shared.DeleteUserResult;
import com.lenin.omena.shared.LoginResult;
import com.lenin.omena.shared.SaveUserInfoResult;
import com.lenin.omena.shared.SaveUserResult;
import com.lenin.omena.shared.domain.Produce;
import com.lenin.omena.shared.domain.User;
import com.lenin.omena.shared.domain.UserInfo;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class AppleMarket implements EntryPoint {
	
	
	private static EventBus eventBus = new SimpleEventBus();
	
	private static UserContext userContext = new UserContext();
	
	private static final AppleMarketServiceAsync appleMarketService = 
			GWT.create(AppleMarketService.class);
	
	private static MainPanel mainPanel;
	
	private static Stack<String> helpMessageStack 
		= new Stack<String>();
	
	public static UserContext getUserContext() {
		return userContext;
	}
	
	public static AppleMarketServiceAsync getService() {
		return appleMarketService;
	}
	
	public static EventBus getEventBus() {
		return eventBus;
	}
	
	
	public static void doLogin(String userName, String password) {
	
		appleMarketService.logIn(userName, password, new AsyncCallback<LoginResult>() {
			
			public void onSuccess(LoginResult result) {
				eventBus.fireEvent(new LoginEvent(result, ActionType.LOGIN));
			}
			
			public void onFailure(Throwable caught) {
				eventBus.fireEvent(new LoginEvent(new LoginResult(null, -1), ActionType.LOGIN));
			}
			
		});
		
	}
	
	
	public static void doLogout() {
		
		appleMarketService.logOut(new AsyncCallback<LoginResult>() {
			
			public void onSuccess(LoginResult result) {
				eventBus.fireEvent(new LoginEvent(result, ActionType.LOGOUT));
			}
			
			public void onFailure(Throwable caught) {
				eventBus.fireEvent(new LoginEvent(new LoginResult(null, -1), ActionType.LOGOUT));
			}
			
		});
		
	}
	
	
	public static void doSaveUser(User user) {
		
		appleMarketService.saveUser(user, new AsyncCallback<SaveUserResult>() {
			
			public void onSuccess(SaveUserResult result) {
				eventBus.fireEvent(new SaveUserEvent(result));
			}
			
			public void onFailure(Throwable caught) {
				eventBus.fireEvent(new SaveUserEvent(new SaveUserResult(null, -1)));
			}
			
		});
		
	}
	
	
	public static void doDeleteUser(User user) {
		
		appleMarketService.deleteUser(user.getKey(), new AsyncCallback<DeleteUserResult>() {
			
			public void onSuccess(DeleteUserResult result) {
				eventBus.fireEvent(new DeleteUserEvent(result));
			}
			
			public void onFailure(Throwable caught) {
				eventBus.fireEvent(new DeleteUserEvent(new DeleteUserResult(null, -1)));
			}
			
		});
		
	}
	
	
	public static void doSaveUserInfo(User user, UserInfo userInfo) {
		
		appleMarketService.saveUserInfo(user.getKey(), userInfo, new AsyncCallback<SaveUserInfoResult>() {
			
			public void onSuccess(SaveUserInfoResult result) {
				eventBus.fireEvent(new SaveUserInfoEvent(result));
			}
			
			public void onFailure(Throwable caught) {
				eventBus.fireEvent(new SaveUserInfoEvent(new SaveUserInfoResult(null, -1)));
			}
			
		});
		
	}
	
	
	public static void doDeleteProduce(User user, Produce produce) {
		
		appleMarketService.deleteProduce(user.getKey(), produce.getKey(), 
				new AsyncCallback<DeleteProduceResult>() {
			
			public void onSuccess(DeleteProduceResult result) {
				eventBus.fireEvent(new ProduceListChangeEvent(result));
			}
			
			public void onFailure(Throwable caught) {
				eventBus.fireEvent(new ProduceListChangeEvent(new DeleteProduceResult(null, -1)));
			}
			
		});
		
	}
	
	
	public static void doAddProduce(User user, Produce produce) {
		
		appleMarketService.addProduce(user.getKey(), produce, 
				new AsyncCallback<AddProduceResult>() {
			
			public void onSuccess(AddProduceResult result) {
				eventBus.fireEvent(new ProduceListChangeEvent(result));
			}
			
			public void onFailure(Throwable caught) {
				eventBus.fireEvent(new ProduceListChangeEvent(new AddProduceResult(null, -1)));
			}
			
			
		});
		
	}
	
	
	public static void doTest(User user, Produce produce) {
		
		appleMarketService.test(user, produce, 
				new AsyncCallback<Integer>() {
			
			public void onSuccess(Integer i) {
				//eventBus.fireEvent(new SaveUserEvent(new SaveUserResult(result.getUser(), false)));
			}
			
			public void onFailure(Throwable caught) {
				//eventBus.fireEvent(new SaveUserEvent(new SaveUserResult(null, false)));
			}
			
		});
		
	}
	
	
	public static void pushHelpMessage(String key, Widget widget) {
		
		userContext.pushHelpMessage(key, widget);
		
		mainPanel.setHelpWidget(widget);
		
	}
	
	
	public static boolean popHelpMessage(String key) {
		
		Widget lastMessage = userContext.popHelpMessage(key);
		
		mainPanel.setHelpWidget(lastMessage);
		
		return lastMessage != null;
		
	}
	
	
	public static boolean replaceHelpMessage(String key, Widget widget) {
		
		Widget lastMessage = userContext.replaceHelpMessage(key, widget);
		
		mainPanel.setHelpWidget(lastMessage);
		
		return lastMessage != null;
		
	}
	
	
	public static void showDialogPopup() {
		
		boolean effective = mainPanel.showDialogPopup();
		
		if(effective) {
			pushHelpMessage("DIALOG", HelpPanel.HELP_DIALOG);
		}
		
	}
	
	public static void hideDialogPopup() {
		
		boolean effective = mainPanel.hideDialogPopup();
		
		if(effective) {
			popHelpMessage("DIALOG");
		}
	
	}
	
	public static MainPanel getMainPanel() {
		return mainPanel;
	}
	
	
	public static void centerMapOnLocation(String location) {
		mainPanel.getMapPanel().centerMapOnLocation(location);
	}
	
	public static String forXML(String text) {
	
		final StringBuilder result = new StringBuilder();
	    
		char[] chars = text.toCharArray();
		
	    for(char c : chars) {
	    	
	      if (c == '<') {
	        result.append("&lt;");
	      }
	      else if (c == '>') {
	        result.append("&gt;");
	      }
	      else if (c == '\"') {
	        result.append("&quot;");
	      }
	      else if (c == '\'') {
	        result.append("&#039;");
	      }
	      else if (c == '&') {
	         result.append("&amp;");
	      }
	      else {
	        result.append(c);
	      }
	      
	    }
	    
	    return result.toString();
	  
	}
	
	
	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		
		String keyParam = Window.Location.getParameter("key");
		
		if(keyParam != null) {
			
			final SimplePanel activatePanel = new SimplePanel();
			activatePanel.getElement().setInnerHTML("Aktivoidaan käyttäjätunnusta...");
			RootPanel.get().add(activatePanel);
			
			appleMarketService.activateUser(keyParam, new AsyncCallback<ActivateResult>() {
				
				public void onSuccess(ActivateResult result) {
					
					if(result.getStatus() == 0) {
						RootPanel.get().remove(activatePanel);
						mainPanel = new MainPanel();
						pushHelpMessage("MAP", HelpPanel.HELP_MAP);
						mainPanel.setHelpWidget(new HTML("Käyttäjätunnuksesi on aktivoitu! Voit nyt kirjautua sisään."));
						RootPanel.get().add(mainPanel);
					} else if(result.getStatus() == 1) {
						activatePanel.getElement().setInnerHTML("Tunnus on jo aktiivinen.");
						Window.Location.replace("http://omenaporssi.appspot.com/");
					} else {
						activatePanel.getElement().setInnerHTML("Aktivointi epäonnistui. Virhekoodi: "+result.getStatus());
					}
					
				}
				
				public void onFailure(Throwable caught) {
					activatePanel.getElement().setInnerHTML("Aktivointivirhe.");
				}
				
			});
			
		} else {
			
			mainPanel = new MainPanel();
			pushHelpMessage("MAP", HelpPanel.HELP_MAP);
			
			RootPanel.get().add(mainPanel);
			
			doLogin("", "");
			
		}
		
		
	}


}
